package collections;

import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

public class KVcomposer {
  //分隔符
  public static final String SEPERATOR = ",";
  public static final String SEPERATOR_2 = ":";
  //装载键值对的map
  private final Map<Integer, Integer> kvMap = new HashMap<Integer, Integer>();

  public KVcomposer() {
  }

  public KVcomposer(String value) {
    put(value);
  }

  public void put(Map<Integer, Integer> map) {
    kvMap.putAll(map);
  }

  public void put(int k, int v) {
    kvMap.put(k, v);
  }

  /**
   * @param value "key:val,key:val..." 格式的键值对String
   */
  public void put(String value) {
    put(value, SEPERATOR, SEPERATOR_2);
  }

  /**
   * @param value 键值对string
   * @param s_1   组分隔符号
   * @param s_2   键值对分隔符号
   */
  public void put(String value, String s_1, String s_2) {
    if (!StringUtils.isBlank(value)) {
      String[] kvArray = value.split(s_1);
      for (String kvStr : kvArray) {
        kvStr = kvStr.trim();
        if (StringUtils.isBlank(kvStr)) {
          continue;
        }

        String[] kv = kvStr.split(s_2);
        if (kv.length != 2) {
          continue;
        }

        String key = kv[0].trim();
        String val = kv[1].trim();
        if (StringUtils.isBlank(key) || StringUtils.isBlank(val)) {
          continue;
        }

        int k = Integer.parseInt(kv[0]);
        int v = Integer.parseInt(kv[1]);
        put(k, v);
      }
    }
  }

  @Override
  public String toString() {
    int i = 0;
    Long[] kvArray = new Long[kvMap.size()];
    for (Entry<Integer, Integer> kv : kvMap.entrySet()) {
      int k = kv.getKey();
      int v = kv.getValue();
      long c = ((widenIntToLong(k)) << Integer.SIZE) | widenIntToLong(v);
      kvArray[i] = c;
      i++;
    }
    Arrays.sort(kvArray);

    StringBuilder sb = new StringBuilder();
    for (i = 0; i < kvArray.length; i++) {
      sb.append(kvArray[i]);
      sb.append(SEPERATOR);
    }

    //去掉最后一个split
    int length = sb.length();
    if (length > 0) {
      sb.setLength(length - SEPERATOR.length());
    }

    return sb.toString();
  }

  public static long[] toKvArray(String composed) {
    if (StringUtils.isBlank(composed)) {
      return new long[0];
    }

    String[] kvStrArray = composed.split(SEPERATOR);
    long[] kvArray = new long[kvStrArray.length];
    for (int i = 0; i < kvStrArray.length; i++) {
      kvArray[i] = Long.parseLong(kvStrArray[i]);
    }
    return kvArray;
  }

  public static int get(String composed, int k, int defaultV) {
    return get(toKvArray(composed), k, defaultV);
  }

  public static int get(long[] kvArray, int k, int defaultV) {
    if (kvArray == null) {
      return defaultV;
    }

    int pos = Arrays.binarySearch(kvArray, (widenIntToLong(k)) << Integer.SIZE);
    if (pos < 0) {
      pos = -(pos + 1);
      if (pos >= kvArray.length) {
        return defaultV;
      }

      if ((int) (kvArray[pos] >> Integer.SIZE) != k) {
        return defaultV;
      }
    }

    return (int) ((kvArray[pos] << Integer.SIZE) >> Integer.SIZE);
  }

  private static long widenIntToLong(int i) {
    return ((long) i) & 0x00000000FFFFFFFFL;
  }

  public static void main(String[] args) {
    long[] longs = new long[]{2, 3, 5, 6, 8};
    int i = get(longs, 1, Integer.MIN_VALUE);
    System.out.println(i);

    System.out.println(widenIntToLong(2));
    System.out.println(Long.toBinaryString(widenIntToLong(2)));
    System.out.println((widenIntToLong(2)) << Integer.SIZE);
    System.out.println("(widenIntToLong(2)) << Integer.SIZE " + Long.toBinaryString((widenIntToLong(2)) << Integer.SIZE));
    System.out.println(Long.MAX_VALUE);
    System.out.println(Long.toBinaryString(Long.MAX_VALUE));
    System.out.println(Long.toBinaryString(Long.MAX_VALUE).length());
    System.out.println(0x00000000FFFFFFFFL);
    System.out.println(Long.toBinaryString(0x00000000FFFFFFFFL));
    System.out.println(Long.toBinaryString(0x00000000FFFFFFFFL).length());

  }

}
